package com.sjgs.gis.quartz;

import com.sjgs.common.utils.CronDateUtils;
import com.sjgs.gis.domain.ScheduleJob;
import com.sjgs.gis.domain.enumeration.JobOperateEnum;
import com.sjgs.gis.common.QuartzFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.time.Instant;

import static com.sjgs.common.Constants.SECOND;

@Service
public class QuartzService {

    private static final Log logger = LogFactory.getLog(QuartzService.class);
    /**
     * 调度器
     */
    @Autowired
    private Scheduler scheduler;

    @Autowired
    private ScheduleJobService scheduleJobService;

    public void initScheduleJob() {
        //查询数据库是否存在需要定时的任务
        scheduleJobService.findAll()
                .collectList()
                .subscribe(scheduleJobs -> {
                    scheduleJobs.forEach(this::addJob);
                });
    }

    public void addJob(ScheduleJob job) {
        if (CronDateUtils.getDate(job.getCronExpression()).before(Date.from(Instant.now()))) {
            String cronStr = CronDateUtils.getCron(Date.from(Instant.now().plusMillis(Math.round(Math.random() * 300) * SECOND)));
            job.setCronExpression(cronStr);
        }
        try {
            //创建触发器
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName())
                    .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
                    .startNow()
                    .build();
            //创建任务
            JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class)
                    .withIdentity(job.getJobName())
                    .build();

            //传入调度的数据，在QuartzFactory中需要使用
            jobDetail.getJobDataMap().put("scheduleJob", job);

            //调度作业
            scheduler.scheduleJob(jobDetail, trigger);

        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    public void operateJob(JobOperateEnum jobOperateEnum, ScheduleJob job) throws SchedulerException {
        JobKey jobKey = new JobKey(job.getJobName());
        switch (jobOperateEnum) {
            case START:
                scheduler.resumeJob(jobKey);
                break;
            case PAUSE:
                scheduler.pauseJob(jobKey);
                break;
            case DELETE:
                scheduler.deleteJob(jobKey);
                break;
        }
    }

    public void startAllJob() throws SchedulerException {
        scheduler.start();
    }

    public void pauseAllJob() throws SchedulerException {
        scheduler.standby();
    }
}
